/**
* name 
*/
module script{
	export class CameraScript extends Laya.Script{
		private gameObject:Laya.Sprite3D;
		private move:boolean;
		private lastTouchX:number = 0;
		private lastTouchY:number = 0;
		private lastTouchScale:number = 0;
		private rx:Laya.Sprite3D;
		private tz:Laya.Sprite3D;
		private mainCamera:Laya.Camera;
		private state:CameraState = CameraState.Free;
		private endTran:Laya.Vector3;
		private NaviCounter:number = 0;
		private MaxNaviCounter:number = 120;
		private curOrien:number = 0;
		private touchDownTime:number;
		private touchDownPosX:number;
		private touchDownPosY:number;
		private static thisObj:CameraScript;
		constructor(){
			super();
		}

		public _load(owner:Laya.Sprite3D):void{
			this.gameObject = owner as Laya.Sprite3D;
		}

		//组件加载完成后初始化 相当于Unity中的Start
		public _start(state:Laya.RenderState):void{
			this.rx = this.gameObject.getChildByName("rx") as Laya.Sprite3D;
			this.tz = this.rx.getChildByName("tz") as Laya.Sprite3D;
			this.mainCamera = this.tz.getChildByName("Main Camera") as Laya.Camera;
		}

		//每帧触发 相当于Unity中的Update
		public _update(state:Laya.RenderState):void{
			if(this.state == CameraState.Lock){	
				this.event("OrienStopped");
				return;
			}
			else if(this.state == CameraState.Navi){	
				this.NaviCounter++;
				if(this.NaviCounter > this.MaxNaviCounter){
					this.state = CameraState.Free;
				}
				else{
					let rot:Laya.Vector3 = new Laya.Vector3();
					Laya.Vector3.lerp(Laya.Vector3.ZERO,this.endTran,1/this.MaxNaviCounter,rot);
					this.gameObject.transform.rotate(new Laya.Vector3(0,rot.y,0),true,false);	
					//this.rx.transform.rotate(new Laya.Vector3(rot.x,0,0),true,true);
					//this.tz.transform.translate(new Laya.Vector3(0,0,rot.z),true);
				}
				
			}
			else{
				if(Math.abs(this.curOrien)>5 && this.gameObject != null){		
					this.gameObject.transform.rotate(new Laya.Vector3(0,this.curOrien*0.002,0),true,false);
					this.event("OrienStarted");
					return;
				}
			}
			this.gameObject.transform.rotate(new Laya.Vector3(0,0.01,0),true,false);	
			this.event("OrienStopped");
		}

		public enableTouch():void{
			this.state = CameraState.Free;
			CameraScript.thisObj = this;
			Laya.stage.on(Laya.Event.MOUSE_DOWN,this,this.onMouseDown);
			Laya.stage.on(Laya.Event.MOUSE_UP,this,this.onMouseUp);
			Laya.Browser.window.addEventListener("deviceorientation",this.orientationHandler,false)
		}

		public disableTouch():void{
			this.state = CameraState.Lock;
			CameraScript.thisObj = null;
			this.curOrien = 0;
			Laya.stage.off(Laya.Event.MOUSE_DOWN,this,this.onMouseDown);
			Laya.stage.off(Laya.Event.MOUSE_UP,this,this.onMouseUp);
			Laya.stage.off(Laya.Event.MOUSE_MOVE,this,this.onMouseMove);
			Laya.Browser.window.removeEventListener("deviceorientation",this.orientationHandler,false)
		}

		private orientationHandler(e:any):void
		{
			let orientation = (Laya.Browser.window.orientation||0);
			if (Laya.stage.canvasRotation)
			{
				if (Laya.stage.screenMode == Laya.Stage.SCREEN_HORIZONTAL)
				orientation +=90;
				else if (Laya.stage.screenMode ==Laya.Stage.SCREEN_VERTICAL)
				orientation-=90;
				//Laya.Browser.window.orientation = orientation;
			}
			if(e.gamma != null){
				//txt.text=e.alpha+"  "+e.beta+"  "+e.gamma;
				CameraScript.thisObj.curOrien = e.gamma;
			}
				
		}

		private onMouseDown(ev:Laya.Event):void{
			if(this.state == CameraState.Navi) return;
			let touches = ev.touches;
			if(touches && touches.length == 2){
				this.lastTouchScale = this.getPointsDistance(touches[0],touches[1]);
			}
			else if(touches && touches.length > 2){

			}
			else{
				this.touchDownPosX = this.lastTouchX = ev.stageX;
				this.touchDownPosY = this.lastTouchY = ev.stageY;
				this.touchDownTime = Date.now();
				Laya.stage.on(Laya.Event.MOUSE_MOVE,this,this.onMouseMove);
			}
			
		}

		private onMouseUp(ev:Laya.Event):void{
			let touches = ev.touches;
			if(touches && touches.length == 2){
				
			}
			else if(touches && touches.length > 2){

			}
			else{
				Laya.stage.off(Laya.Event.MOUSE_MOVE,this,this.onMouseMove);
				if(Date.now() - this.touchDownTime < 300){	
					if(ev.stageX - this.touchDownPosX < -150){
						this.event(Laya.Event.DRAG_END,-1);
					}
					else if(ev.stageX - this.touchDownPosX > 150){
						this.event(Laya.Event.DRAG_END,1);
					}
				}
				
			}
		}

		private onMouseMove(ev:Laya.Event):void{
			let touches = ev.touches;
			if(touches && touches.length == 2){
				let newTouchScale = this.getPointsDistance(touches[0],touches[1]);
				let moveZ = 0.02 * (newTouchScale - this.lastTouchScale);
				let newZ = this.tz.transform.localPosition.z + moveZ;
				if(newZ >= -35 && newZ <= -1){
					this.tz.transform.localPosition = new Laya.Vector3(0,0,newZ);
				}
				
				this.lastTouchScale = newTouchScale;
			}
			else if(touches && touches.length > 2){

			}
			else{
				let rotY = 0.01*(ev.stageX - this.lastTouchX);
				let rotX = 0.01*(ev.stageY - this.lastTouchY);
				this.gameObject.transform.rotate(new Laya.Vector3(0,-rotY*3,0),true,false);
				let newRX = this.rx.transform.localRotationEuler.x + rotX;
				if(newRX >= 10 && newRX <= 60){
					//this.rx.transform.rotate(new Laya.Vector3(rotX,0,0),true,false);		
				}
					
				
				this.lastTouchX = ev.stageX;
				this.lastTouchY = ev.stageY;
			}
		}

		private getPointsDistance(a:any,b:any):number
		{
			let dx = a.stageX - b.stageX;
			let dy = a.stageY - b.stageY;
			return Math.sqrt(dx * dx + dy * dy);
		}

		public moveTo(pos:Laya.Vector3,from:number,dir:number):void{
			if(this.state == CameraState.Free){
				this.state = CameraState.Navi;
				this.NaviCounter = 0;
				let targeQ = new Laya.Quaternion();
				Laya.Quaternion.lookAt(Laya.Vector3.ZERO,pos,Laya.Vector3.Up,targeQ);
				let targetAngle = new Laya.Vector3();
				targeQ.getYawPitchRoll(targetAngle);
				//pitch 绕x轴旋转
				let cameraXRot = this.rx.transform.localRotationEuler.x;
				//yaw 绕y轴旋转 通过节点坐标计算出的RotationEuler.y和相机在该节点位置对应的RotationEuler.y是相反的，所以这里要取负统一到节点所在坐标系。
				let cameraYRot = -this.gameObject.transform.localRotationEuler.y;
				// 计算相机缩放
				let zTranslate =  Math.abs(this.tz.transform.localPosition.z) - Laya.Vector3.scalarLength(pos);
				this.endTran = new Laya.Vector3(targetAngle.z - cameraXRot + 0.4,cameraYRot-targetAngle.x * 180 / Math.PI,zTranslate);
				console.log(this.endTran);
			}
		}

		public playZoomInAnimation():void{
			let ani = this.gameObject.getComponentByType(Laya.Animator) as Laya.Animator;
			ani.play("CamAnimation");
		}
	}

	enum CameraState {Free, Lock, Navi}
}